#!/usr/bin/python
import threading
import time
import madsutil
from random import randint
from urllib2 import urlopen
from urllib2 import build_opener
from bs4 import BeautifulSoup, SoupStrainer
from pymongo import MongoClient
from bson.objectid import ObjectId
from madsutil import log
from madsutil import logt
from madsutil import url_fix


class CardParser(threading.Thread):
    '''
    This working class parse the detail of a single cards
    and save it on database
    as a separate thread
    '''
    
    def __init__(self, appender=None,q=None,ql=None,name='name',simulate=False, update = False):
        super(CardParser, self).__init__()
        self._appender = appender
        self._queue = q
        self._queueLock = ql
        self._name = name
        self._simulate=simulate
        self._update = update

        log('[Parser' +self._name +'] Connection to DB: '+madsutil.DB_URL+":"+madsutil.DB_NAME,self._appender)
        self.client = MongoClient(madsutil.DB_URL)
        db = self.client[madsutil.DB_NAME]
        self.cards = db.cards
        
    
    def run(self):
        print '[Parser' +self._name +'] Start'
        while not madsutil.END_FLAG:
            if not self._queue.empty():
                self._queueLock.acquire()
                card = self._queue.get() 
                self._queueLock.release()
                try:
                    card = self.parse_card(card)
                    #insert or update card into db
                    if not self._simulate:
                        if "_id" in card:
                            self.cards.save(card)
                            log('[Parser' +self._name +']'+' Update Card[' +str(card['name'])+'] with id: ' + str(ObjectId(card["_id"])) , self._appender)
                        else:
                            card_id = self.cards.insert(card)
                            log('[Parser' +self._name +']'+' Insert Card[' +str(card['name'])+'] with id: ' + str(ObjectId(card_id)) , self._appender)

                    log('[Parser' +self._name +'] Processed: ' + str(card),self._appender)
                    time.sleep(0.1)
                except Exception as e:
                    log('[Parser' +self._name +'] Card name: ' + card['name'],self._appender)
                    log( '[Parser' +self._name +'] Card link: ' + card['link'],self._appender)
                    log( '[Parser' +self._name +'] Unable to parse this card: '+str(e),self._appender)
                    log(str(card),self._appender)
                    #put card into queue
                    time.sleep(1)
            else:
                log('[Parser' +self._name +'] Queue empty: wait',self._appender)
                time.sleep(2.5)

        #close connection
        self.client.close()
        log('[Parser' +self._name +'] EndFlag : finish',self._appender)
    
    def parse_card(self,card):
        '''open the card link,parse the card detail from 
        gatherer.wizards.com, and add the founded attribute to selected
        card and return it'''
        start_det_time = time.time()
        opener = build_opener()
        #opener.addheaders = [('User-agent', 'Mozilla/5.0')]
        opener.addheaders = [('User-agent', 'Custom-user-agent')]
        html = opener.open(card['link'].encode('utf-8')).read()
        log('[Parser' +self._name +']'+'open link: ' + card['link'].encode('utf-8'),self._appender)
        #html = urlopen(card['link'].encode('utf-8')).read()
        logt( '[Parser' +self._name +']'+ 'url http://deckbox.org open in',start_det_time,self._appender)
        divparse = SoupStrainer('div',{'class': 'card_page'})
        elapse = time.time()
        page = BeautifulSoup(html,parse_only=divparse)
        logt( '[Parser' +self._name +']'+ 'Parse http://deckbox.org content in',elapse,self._appender)
        price_min = page.find("div", {"class" : "price price_min"}).contents[0].string.strip()
        price_avg = page.find("div", {"class" : "price price_avg"}).contents[0].string.strip()
        price_hig = page.find("div", {"class" : "price price_hig"}).contents[0].string.strip()
        
        prices = {'price_min':price_min,
                  'price_avg':price_avg,
                  'price_hig':price_hig};
        #print prices
        card['prices']=prices
        
       
        
                
            
            
        card['img_link'] = url_fix('http://deckbox.org'+page.find("img", {"id": "card_image"})['src'] )
        
        cardprop = page.find("table", {"class" : "card_properties"})
        elapse = time.time()
        for row in cardprop.findAll('tr'):
            cols = row.findAll('td');
            for c in cols:
                if c.contents[0] == 'Editions':
                    images = cols[1].findAll('img')
                    editions = []
                    for img in images:
                        editions.append(img['alt'])
                    card['editions']=editions
                if c.contents[0] == 'Formats':
                    card['formats'] = cols[1].contents[0].strip();
                if c.contents[0] == 'Rulings':
                    card['gatherer_page'] = url_fix(cols[1].find('a')['href'])
                if c.contents[0] == 'Flavor':
                    card['flavor'] = cols[1].contents[0].strip();
        logt( '[Parser' +self._name +']'+'retrieve all from deckbox in',elapse,self._appender)
            
        '''find other attributes on http://gatherer.wizards.com '''
        elapse = time.time()
        html = urlopen(card['gatherer_page'].encode('utf-8')).read()
        logt( '[Parser' +self._name +']'+'url gatherer open in',start_det_time,self._appender)
        tablesparse = SoupStrainer('div',{"class":"contentcontainer"})
        #tablesparse = SoupStrainer('td',{"class":"rightCol"})
        elapse = time.time()
        page = BeautifulSoup(html,parse_only=tablesparse)
        madsutil.logt( '[Parser' +self._name +']'+'Parse gatherer page content in',elapse,self._appender)
        _double = False;
        #cxheck if it is a double card
        tables = page.findAll("table",{'class':'cardDetails'})
        if len(tables)>1:
            _double = True
        
        card['double'] = _double
    
        
    
        
        elapse = time.time()
        '''Carta principale'''
        divs = tables[0].findAll("div",{'class':'row'})
        for d in divs:
            #card[d.find('div',{'class':'label'}).text.strip()].append(d.find('div',{'class':'value'}))
            if d.find('div',{'class':'label'}).text.strip() == 'Card Name:':
                name_found = d.find('div',{'class':'value'}).text.strip()
                if(name_found != card['name']):
                    log( '[Parser' +self._name +']'+'ERROR: parsing the wrong page',self._appender)
                        
            if d.find('div',{'class':'label'}).text.strip() == 'Mana Cost:':
                images = d.find("div",{"class":"value"}).findAll('img');
                manas = []
                for img in images:
                    manas.append(img['alt'])
                #print manas
                card['mana']=manas
                continue
                
            if d.find('div',{'class':'label'}).text.strip() == 'Converted Mana Cost:':
                cmc = d.find('div',{'class':'value'}).text.strip()
                card['cmc'] = cmc
                continue
            
            if d.find('div',{'class':'label'}).text.strip() == 'Types:':
                typ = d.find('div',{'class':'value'}).text.strip()
                card['type'] = typ
                continue
            
            if d.find('div',{'class':'label'}).text.strip() == 'Card Text:':
                text_value = d.find("div",{'class':'value'}).findAll("div",{'class':'cardtextbox'})
                rules = ''
                for divs in text_value:
                    images = divs.findAll('img')
                    if images:
                        for img in images:
                            rules = rules + str(img['alt'])+','
                    rules = rules + divs.text.strip()+'\n'
                card['rules'] = rules
                continue
            
            if d.find('div',{'class':'label'}).text.strip() == 'P/T:':
                pt = d.find('div',{'class':'value'}).text.strip()
                card['p'] = pt.split('/')[0].strip()
                card['t'] = pt.split('/')[1].strip()
                continue
        
            if d.find('div',{'class':'label'}).text.strip() == 'Expansion:':
                expansion = d.find('div',{'class':'value'}).text.strip()
                card['expansion'] = expansion
                continue
        
            if d.find('div',{'class':'label'}).text.strip() == 'Rarity:':
                rarity = d.find('div',{'class':'value'}).text.strip()
                card['rarity'] = rarity
                continue
            
            if d.find('div',{'class':'label'}).text.strip() == 'Community Rating:':
                rating = d.find('div',{'class':'value'}).text.strip()
                card['rating'] = rating[rating.index(':')+1:rating.index('/')]
                continue
        
            if d.find('div',{'class':'label'}).text.strip() == 'Color Indicator:':
                color = d.find('div',{'class':'value'}).text.strip()
                card['color'] = color
                continue
        '''Gestione carta doppia'''
        
        if _double:
            divs = tables[1].findAll("div",{'class':'row'})
            for d in divs:
                
                if d.find('div',{'class':'label'}).text.strip() == 'Mana Cost:':
                    images = d.find("div",{"class":"value"}).findAll('img');
                    manas = []
                    for img in images:
                        manas.append(img['alt'])
                    #print manas
                    card['mana_d'] = manas
                    continue
                    
                if d.find('div',{'class':'label'}).text.strip() == 'Converted Mana Cost:':
                    cmc = d.find('div',{'class':'value'}).text.strip()
                    card['cmc_d'] = cmc
                    continue
                
                if d.find('div',{'class':'label'}).text.strip() == 'Types:':
                    typ = d.find('div',{'class':'value'}).text.strip()
                    card['type_d'] = typ
                    continue
                
                if d.find('div',{'class':'label'}).text.strip() == 'Card Text:':
                    text_value = d.find("div",{'class':'value'}).findAll("div",{'class':'cardtextbox'})
                    rules = ''
                    for divs in text_value:
                        images = divs.findAll('img')
                        if images:
                            for img in images:
                                rules = rules + str(img['alt'])+','
                        rules = rules + divs.text.strip()+'\n'
                    card['rules_d'] = rules
                    continue
                
                if d.find('div',{'class':'label'}).text.strip() == 'P/T:':
                    pt = d.find('div',{'class':'value'}).text.strip()
                    card['p_d'] = pt.split('/')[0].strip()
                    card['t_d'] = pt.split('/')[1].strip()
                    #card['pt_d'].append(pt)
                    continue
                
                if d.find('div',{'class':'label'}).text.strip() == 'Color Indicator:':
                    color = d.find('div',{'class':'value'}).text.strip()
                    card['color_d'] = color
                    continue
                
        logt( '[Parser' +self._name +']'+'end tables routines in',elapse,self._appender)
        logt( '[Parser' +self._name +']'+'end card in',start_det_time,self._appender)
        return card
    